package cn.tedu.charging.cost.dao.repository.impl;

import cn.tedu.charging.common.utils.JsonUtils;
import cn.tedu.charging.cost.dao.repository.CostRuleCacheRepository;
import cn.tedu.charging.cost.pojo.po.CostRulePO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;

@Slf4j
@Repository
public class CostRuleCacheRepositoryImpl implements CostRuleCacheRepository {

    @Autowired  //Repository通过RedisTemplate操作redis，所以要注入。类似于Repository通过mapper操作数据库，就要注入mapper一样。
    private RedisTemplate<String, Serializable> redisTemplate;

    @Override
    public void saveCostRule(Integer stationId, List<CostRulePO> costRulePOS) {
        //用别的opsFor也行，不过test就测了个ForValue，所以先用个简单的
        //valueOperations类似一个map
        ValueOperations<String, Serializable> valueOperations = redisTemplate.opsForValue();
        String costRuleKey = "COST_RULE_KEY_" + stationId;
        String json = JsonUtils.toJson(costRulePOS);
        valueOperations.set(costRuleKey, json);
    }

    @Override
    public List<CostRulePO> getCostRuleByStationId(Integer stationId) {

        ValueOperations<String, Serializable> valueOperations = redisTemplate.opsForValue();
        String costRuleKey = "COST_RULE_KEY_" + stationId;
        Serializable serializable = valueOperations.get(costRuleKey);   //获取对应value的字节数组？
        log.debug("通过站点id:{},从Redis获取计价规则:{}", stationId, serializable);
        if (serializable != null) {
            //这个会导致小刀cost测试时，报LinkedHashMap转换CostRulePO错误，所以专门写个方法转。因为json本质是K-V的，所以代码把json当做LinkedHashMap
            //return JsonUtils.fromJson(String.valueOf(serializable), List.class);
            return getCostRulePOS(serializable);
        }
        return Collections.emptyList();
    }

    /**
     * 对象转换为json hutool 自己了解
     * @param serializable
     * @return
     */
    private List<CostRulePO> getCostRulePOS(Serializable serializable){
        //[CostRuleA,CostRuleB,CostRuleC] 不能直接转换为 List<CostRule>
        //循环数组 一个一个转 转完后,在放到List<CostRule>
        List<CostRulePO> result = new ArrayList<>();
        List<LinkedHashMap<String,CostRulePO>> mapList = JsonUtils.fromJson(String.valueOf(serializable), List.class);
        //debug运行，看到站点为5时，查到的mapList是长度为5的ArrayList，
        // 里面每条数据都是一条计价规则的LinkedHashMap,里面具体的k-v就是id-1，name-尖上午这样的。因为有顺序，所以是 Linked HashMap
        //
        mapList.forEach(e->{    //e就是循环的具体数据,相当于下面注释的stringCostRulePOLinkedHashMap
            //CostRulePO costRulePO = JsonUtils.fromJson(String.valueOf(e), CostRulePO.class);//但这个还是转换不了保存，需要用convertValue
            CostRulePO costRulePO = JsonUtils.convertValue(e, CostRulePO.class);//把对象e转成json，在JsonUtils加上这个方法convertValue
            result.add(costRulePO);
        });
        //for (LinkedHashMap<String,CostRulePO> stringCostRulePOLinkedHashMap : mapList){}
        return result;
    }


}
